package gu.sql2java.wherehelper;

import static gu.sql2java.SimpleLog.logString;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;

/**
 * 变量测试类型
 * @author guyadong
 * @since 3.25.0
 */
public enum VarTestType {
	/** 测试变量为{@code null} */NULL("isNull(${var})"),
	/** 测试变量为非{@code null} */NONULL("isNonull(${var})"),
	/** 测试变量为空 */EMPTY("isEmpty(${var})"),
	/** 测试变量为非空 */NOEMPTY("!isEmpty(${var})"),
	/** 测试变量为{@code true} */TRUE("isTrue(${var})"),
	/** 测试变量为{@code false} */FALSE("isFalse(${var})"),
	/** 等价或包含表达式 */EQUALORIN("isNonull(${var}) && eqin(${var},${value})"),
	/** 等价或包含表达式 */NOEQUALORIN("isNonull(${var}) && !eqin(${var},${value})"),
	/** 等价表达式 */EQUAL("isNonull(${var}) && eq(${var},${value})"),
	/** 等价表达式 */NOEQUAL("isNonull(${var}) && !${var}.equals(${value})"),
	/** 算术比较表达式 */COMPARE("isNonull(${var}) && (${var})${op}(${value})");
	public final String tmpl;
	/** 操作对象数量 */
	public final int opcount;
	private VarTestType(String tmpl) {
		this.tmpl = tmpl;
		Matcher matcher = Pattern.compile("\\$\\{(\\w+)\\}").matcher(tmpl);
		Set<String> ops = Sets.newHashSet();;
		while(matcher.find()) {
			ops.add(matcher.group(1));
		}
		this.opcount=ops.size();
	}
	public String render(String var) {
		checkVarTestType(this,1);
		return tmpl.replace("var", String.valueOf(var));
	}
	public String render(String var,CompareOp op, Object value,boolean quote,boolean refValue) {
		if(opcount == 3 && null == op) {
			throw new WhereHelperException("op is null");
		}
		if(refValue && (! (value instanceof String) || ((String)value).isEmpty())) {
			throw new WhereHelperException("no empty string required for value if refValue is true");
		}
		if(COMPARE.equals(this)) {
			switch(op) {
			case EQ:
				return EQUAL.render(var, op, value, quote, refValue);
			case NE:
				return NOEQUAL.render(var, op, value, quote, refValue);
			default:
				break;
			}
		}
		String vs = String.valueOf(value);
		if(!refValue && quote) {
			vs = JSON.toJSONString(vs) ;
		}
		String exp = tmpl.replace("var", String.valueOf(var)).replace(refValue?"value":"${value}",vs);
		if(null != op) {
			exp = exp.replace("${op}", op.jop);
		}
		return  exp;
	}
	static VarTestType checkVarTestType(VarTestType testType,int opcount) {
		if(null == testType || testType.opcount!= opcount) {
			throw new WhereHelperException(
					logString("INVALID VarTestType {},opcount {} required,such as:{}",
							String.valueOf(testType), opcount, Joiner.on(',').join(values(opcount))) );
		}
		return testType;
	}
	/**
	 * 根据返回所有{@link #}匹配输入参数的枚举变量
	 * @param opcount
	 */
	static List<VarTestType> values(int opcount) {
		return Arrays.asList(values()).stream().filter(v->v.opcount==1).collect(Collectors.toList());
	}
}
